package cn.yj.common.controller;

import cn.yj.api.FileUploadHandler;
import cn.yj.common.emums.PayFrom;
import cn.yj.common.emums.PayType;
import cn.yj.common.entity.AliPayResult;
import cn.yj.common.exception.PayException;
import cn.yj.common.factory.PayTypeFactory;
import cn.yj.common.service.PaySuccessNotifyHandler;
import cn.yj.commons.StringPools;
import cn.yj.commons.utils.QrUtils;
import cn.yj.commons.utils.ServletUtils;
import cn.yj.entity.BController;
import cn.yj.entity.ByteEntity;
import cn.yj.entity.R;
import cn.yj.tools.exception.ServiceException;
import cn.yj.wx.pay.enrity.Amount;
import cn.yj.wx.pay.enrity.Payer;
import cn.yj.wx.pay.enrity.WechatPayRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author 永健
 * @since 2021-09-23 13:38
 */
@RequestMapping("/pay")
@RestController
public class TestPayController extends BController {

    private static final Logger log = LoggerFactory.getLogger(TestPayController.class);

    @RequestMapping(path = "/testAliPay")
    public R testPayAli(String payType, String payFrom, String openid) throws Exception {


        // H5 和 PC 的支付请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("totalAmount", "0.1");
        params.put("outTradeNo", String.valueOf(System.currentTimeMillis()));
        params.put("subject", "iPhone 13 128G");
        params.put("timeoutExpress", "5m");


        if (PayType.WECHAT.name().equals(payType)) {
            WechatPayRequest wechatPayRequest = new WechatPayRequest("测试支付",
                    String.valueOf(System.currentTimeMillis()), new Amount(BigDecimal.ONE), new Payer("oCfzx4utpj" +
                    "-gy9XlG5TppTEu12gs"), null);
            // 非JSPI支付不需要
            if (!PayFrom.JSAPI.name().equals(payFrom)) {
                wechatPayRequest.setPayer(null);
            }

            if (PayFrom.H5.name().equals(payFrom)) {
                JSONObject sceneInfo = new JSONObject();
                sceneInfo.put("payer_client_ip", "127.0.0.1");
                JSONObject h5Info = new JSONObject();
                h5Info.put("type", "Wap");
                sceneInfo.put("h5_info", h5Info);
                wechatPayRequest.setScene_info(sceneInfo);
            }
            params = JSONObject.parseObject(JSON.toJSONString(wechatPayRequest), Map.class);
        }


        AliPayResult payResult;
        try {
            payResult =
                    PayTypeFactory.build(PayType.valueOf(payType), PayFrom.valueOf(payFrom)).selectExecutor().underOrder(params);
        } catch (PayException | ServiceException w) {
            throw new ServiceException(w.getMessage());
        }


        if (PayFrom.NATIVE.name().equals(payFrom)) {
            ByteArrayOutputStream qrGen = QrUtils.createQrGen(payResult.getBody().get("body").toString());
            ByteEntity byteEntity = new ByteEntity(qrGen.toByteArray(),
                    "payCode".concat("/").concat(UUID.randomUUID().toString().concat(StringPools.JPG)));
            byteEntity.setContentType("image/jpeg");
            String codeUrl = FileUploadHandler.getInstant().upload(byteEntity);
            payResult.getBody().put("body", codeUrl);
        }
        return R.success().setData(payResult);
    }

    @Resource
    PaySuccessNotifyHandler notify;

    /**
     * 支付宝支付结果异步通知
     *
     * @param params
     */
    @RequestMapping(path = "/alipay.notify.url")
    public void notice(@RequestParam Map<String, String> params) {
        try {
            notify.syncNotify(PayType.ALIPAY, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        PrintWriter writer = null;
        try {
            writer = ServletUtils.getResponse().getWriter();
            writer.write("success");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.flush();
            }
        }
    }

    /**
     * 支付宝支付同步回调接口用于【网站支付】
     *
     * @param params
     */
    @RequestMapping(path = "/alipay.return.url")
    public void returnMethod(@RequestParam Map<String, Object> params, HttpServletResponse response) throws IOException {
        response.sendRedirect("http://127.0.0.1:8087/#/paySuccess");
    }


    @RequestMapping("/wechat.notify.url")
    public Map<String, Object> wxPayNotice(@RequestBody Map<String, Object> body) {
        Map<String, Object> map = getMap("code", "SUCCESS");
        map.put("message", "成功");
        try {
            notify.syncNotify(PayType.WECHAT, body);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", "ERROR");
            map.put("message", "失败");
        }
        return map;
    }
}
